﻿
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using ClosedXML.Excel;
using Test30.Core;
using Test30.Engine;
using Test30.Util;

namespace Test30.Tools.Reports
{
    public class StatsOutput
    {
        public StatsOutput()
        {
            stats = new AsyncStats();

            //ToTxt(stats.StatRows);
            //ToExcel(stats.StatRows);
            RaceToExcel(stats.Races);
            //Generate();
        }

        private void RaceToExcel(Dictionary<Race, RaceStat> races)
        {
            var wb = new XLWorkbook();
            DataTable dt = new DataTable();
            dt.TableName = "Sheet1";
            dt.Columns.Add(new DataColumn("name", typeof(string)));
            dt.Columns.Add(new DataColumn("glyph", typeof(string)));
            dt.Columns.Add(new DataColumn("art", typeof(string)));
            int line = 0;
            foreach (KeyValuePair<Race, RaceStat> race in races)
            {
                dt.Rows.Add(dt.NewRow());
                var glyph = ((Character) race.Key.Appearance).Glyph.ToString();
                dt.Rows[line][0] = race.Key.Name;
                dt.Rows[line][1] = glyph;
                dt.Rows[line][2] = glyph.RemoveSuffix(5);
                line++;
            }
            wb.Worksheets.Add(dt);
            wb.SaveAs("../../../../Output/Excels/races.xlsx");
        }

        private void ToExcel(IEnumerable<IStatRow> stats)
        {
            var statRows = stats as IList<IStatRow> ?? stats.ToList();

            var wb = new XLWorkbook();
//            var wsRaces = wb.Worksheets.Add("races");
//            wsRaces.Cell("B1").Value = "test";

            GenerateStats();

            var selectStatRows = statRows.Take(10);
            DataTable dt = new DataTable();
            dt.TableName = "Sheet1";

            int line = 0;
            foreach (IStatRow row in selectStatRows)
            {
                dt.Columns.Add(new DataColumn($"{row.Name}", typeof(float)));
                int column = 0;
                foreach (int cell in row.Values)
                {
                    if (line == 0)
                        dt.Rows.Add(dt.NewRow());
                    int max = row.Max(column);
                    float normal = 0.0f;
                    if (max > 0)
                        normal = cell.Clamp(0, max).Normalize(0, max);

                    dt.Rows[column][line] = normal;
                    column++;
                }
                line++;
            }

            wb.Worksheets.Add(dt);
            wb.SaveAs("../../../../Output/Excels/races.xlsx");
        }

        private void ToTxt(IEnumerable<IStatRow> stats)
        {
            var statRows = stats as IList<IStatRow> ?? stats.ToList();

            FileStream file = new FileStream("../../../../Output/Txt/races.txt", FileMode.Create);
            StreamWriter sw = new StreamWriter(file);

            GenerateStats();

            var selectStatRows = statRows.Take(10);
            DataTable dt = new DataTable();
            dt.TableName = "Sheet1";

            int line = 0;
            foreach (IStatRow row in selectStatRows)
            {
                dt.Columns.Add(new DataColumn($"{row.Name}", typeof(float)));
                int column = 0;
                foreach (int cell in row.Values)
                {
                    if (line == 0)
                        dt.Rows.Add(dt.NewRow());
                    int max = row.Max(column);
                    float normal = 0.0f;
                    if (max > 0)
                        normal = cell.Clamp(0, max).Normalize(0, max);

                    dt.Rows[column][line] = normal;
                    column++;
                }
                line++;
            }

            foreach (DataRow row in dt.Rows)
            {
                string str = string.Empty;
                foreach (var o in row.ItemArray)
                {
                    str += $"{o.ToString()}\t";
                }
                sw.WriteLine(str);
            }


            sw.Close();
        }

        void GenerateStats()
        {
            for (int level = 1; level <= 100; level++)
            {
                for (int j = 0; j < 1000; j++)
                {
                    // let the level wander
                    int monsterLevel = Rng.WalkLevel(level).Clamp(1, 100);
                    // pick a race
                    Race race = stats.Content.Races.RandomSoft(monsterLevel);
                    int count = stats.Races[race].Increment(level);
                    stats.MaxRaceCount = Math.Max(stats.MaxRaceCount, count);
                    stats.MaxRaceCounts[level - 1] = Math.Max(stats.MaxRaceCounts[level - 1], count);
                }
            }
        }

        void Generate()
        {
            HashSet<string> hashSet = new HashSet<string>();
            for (int i = 0; i < 1000; i++)
            {
                Race race = stats.Content.Races.RandomSoft(50);
                if(!hashSet.Contains(race.Name))
                    hashSet.Add(race.Name);
                //stats.Races[race].Increment(1);
            }
        }


        private AsyncStats stats;
    }
}
